import { useAPIUtils } from "@/components/APIUtilsProvider";
import EmptyListPlaceholder from "@/components/EmptyListPlaceHolder";
import PageLayout from "@/components/PageLayout";
import When from "@/components/When";
import {
  Button,
  Center,
  Flex,
  Group,
  Modal,
  Pagination,
  Paper,
  ScrollArea,
  Select,
  Table,
  Text,
  TextInput,
  Textarea,
  Title,
} from "@mantine/core";
import { useForm } from "@mantine/form";
import { useDisclosure } from "@mantine/hooks";
import { IconPlus, IconSearch } from "@tabler/icons-react";
import dayjs from "dayjs";
import { useImmer } from "use-immer";
import DictionaryItemText from "../../components/DictionaryItemText";

import { modals } from "@mantine/modals";

export default function ProtocolList() {
  const {
    restGET,
    tanstackQuery,
    tanstackInvalidate,
    restPOST,
    restPUT,
    restDELETE,
  } = useAPIUtils();

  const [editModalOpened, editModalHandlers] = useDisclosure(false);

  const [pagingCondition, setPagingCondition] = useImmer({
    type: "",
    pageIndex: 0,
    pageSize: 10,
  });

  const searchForm = useForm({
    mode: "uncontrolled",
    initialValues: {
      type: "",
    },
    validate: {},
  });

  const search = (values) => {
    tanstackInvalidate(`/api/admin/protocols`);
    setPagingCondition({
      ...values,
      pageSize: pagingCondition.pageSize,
      pageIndex: 0,
    });
  };

  const typeQuery = tanstackQuery(`/api/dictionaries/protocol_type`);

  const types = typeQuery.data
    ? Object.entries(typeQuery.data).map(([key, value]) => ({
        label: value.text,
        value: key,
      }))
    : [];

  const protocolQuery = tanstackQuery(`/api/admin/protocols`, {
    ...pagingCondition,
    type: pagingCondition.type || "",
    pageNo: pagingCondition.pageIndex,
    pageSize: pagingCondition.pageSize,
  });

  const totalPages = protocolQuery.data?.totalPages;
  const rows = protocolQuery.data?.content.map((protocol, index) => (
    <Table.Tr key={index}>
      <Table.Td>
        <Text>{index + 1}</Text>
      </Table.Td>

      <Table.Td>
        <DictionaryItemText dictName="protocol_type" itemKey={protocol.type} />
      </Table.Td>

      <Table.Td>
        <Text>{protocol.title}</Text>
      </Table.Td>

      <Table.Td>
        {dayjs(protocol.createdAt).format("YYYY/MM/DD HH:mm")}
      </Table.Td>

      <Table.Td>
        <Group>
          <Button
            variant="subtle"
            size="xs"
            onClick={() => showProtocolContent({ ...protocol })}
          >
            详细内容
          </Button>
        </Group>
      </Table.Td>
    </Table.Tr>
  ));

  return (
    <PageLayout title={"协议列表"}>
      <form onSubmit={searchForm.onSubmit(search)}>
        <Flex
          mih={50}
          mb={44}
          gap="md"
          justify="space-between"
          align="flex-end"
          direction="row"
          wrap="wrap"
        >
          <Button
            variant="light"
            aria-label="add"
            rightSection={<IconPlus size={14} />}
            onClick={editModalHandlers.open}
          >
            发布新协议
          </Button>

          <Flex justify="flex-end" align="flex-end" gap={"md"}>
            <Select
              clearable
              placeholder="默认全部"
              label="分类"
              {...searchForm.getInputProps("type")}
              data={types}
            />
            <Button type="submit" rightSection={<IconSearch size={14} />}>
              搜索
            </Button>
          </Flex>
        </Flex>
      </form>

      <When condition={rows?.length > 0}>
        <Paper p="md">
          <Table verticalSpacing={"sm"}>
            <Table.Thead>
              <Table.Tr>
                <Table.Th w={"3%"}></Table.Th>
                <Table.Th w={"15%"}>分类</Table.Th>
                <Table.Th w={"55%"}>标题</Table.Th>
                <Table.Th w={"10%"}>发布时间</Table.Th>
                <Table.Th>操作</Table.Th>
              </Table.Tr>
            </Table.Thead>
            <Table.Tbody>{rows}</Table.Tbody>
          </Table>
        </Paper>
        <Center mt={40}>
          <Pagination
            total={totalPages}
            value={pagingCondition.pageIndex + 1}
            onChange={(e) => {
              setPagingCondition({ ...pagingCondition, pageIndex: e - 1 });
            }}
          />
        </Center>
      </When>
      <When condition={rows?.length == 0}>
        <EmptyListPlaceholder />
      </When>
      <EditModal
        protocolTypes={types}
        opened={editModalOpened}
        handlers={editModalHandlers}
      />
    </PageLayout>
  );
}

const showProtocolContent = ({ title, content }) =>
  modals.open({
    title: (
      <Text size="sm" fs={"italic"} c="dimmed">
        协议内容
      </Text>
    ),
    size: 800,
    children: (
      <ScrollArea h={800} p="md">
        <Title align="center" order={3} mb={40}>
          {title}
        </Title>
        <Text style={{ whiteSpace: "pre-wrap" }}>{content}</Text>
      </ScrollArea>
    ),
  });

function EditModal({ protocolTypes, opened, handlers }) {
  const { tanstackInvalidate, restPUT } = useAPIUtils();

  const form = useForm({
    mode: "uncontrolled",
    initialValues: {
      type: "",
      title: "",
      content: "",
    },

    validate: {
      type: (value) => (/^[^\s]+$/.test(value) ? null : "请选择分类"),
      title: (value) => (/^(?!\s*$).+/.test(value) ? null : "标题不能为空"),
      content: (value) => (/^(?!\s*$).+/.test(value) ? null : "内容不能为空"),
    },
  });

  const releaseProtocol = async (values) => {
    await restPUT(`/api/admin/protocols`, values);
    tanstackInvalidate(`/api/admin/protocols`);
    closeModal();
  };

  const closeModal = () => {
    handlers.close();
    form.reset();
  };

  return (
    <Modal
      opened={opened}
      onClose={closeModal}
      title="发布新协议"
      centered
      size={800}
    >
      <form onSubmit={form.onSubmit(releaseProtocol)}>
        <Select
          label="所属分类"
          {...form.getInputProps("type")}
          data={protocolTypes}
        />

        <TextInput withAsterisk label="标题" {...form.getInputProps("title")} />

        <Textarea
          autosize
          minRows={20}
          withAsterisk
          label="内容"
          {...form.getInputProps("content")}
        />

        <Group justify="flex-end" mt="md">
          <Button type="submit">发布</Button>
        </Group>
      </form>
    </Modal>
  );
}
